<template>
  <div class="comp-tree">
    <el-card class="box_card">
      <div slot="header" class="header_box">
        <div class="select_wrapper">
          <el-select
            v-model="selectValue"
            @change="selectChange"
            placeholder="请选择"
          >
            <el-option
              v-for="item in options"
              :key="item.id"
              :label="item.name"
              :value="item.id"
            >
            </el-option>
          </el-select>
        </div>
      </div>
      <!-- tree -->
      <el-tree
        ref="SlotTree"
        :data="setTree"
        v-loading="loading"
        :default-expanded-keys="defaultShowNodes"
        :props="defaultProps"
        :expand-on-click-node="false"
        highlight-current
        node-key="id"
      >
        <div class="comp-tr-node" slot-scope="{ node, data }">
          <!-- 编辑状态 -->
          <template v-if="node.isEdit">
            <el-input
              v-model="data.name"
              autofocus
              size="mini"
              :ref="'slotTreeInput' + data[NODE_KEY]"
              @blur.stop="handleInput(node, data)"
              @keyup.enter.native="handleInput(node, data)"
            ></el-input>
          </template>

          <!-- 非编辑状态 -->
          <template v-else>
            <!-- 名称： 新增节点增加class（is-new） -->
            <span class="comp-tr-node--name">
              {{ node.label }}
            </span>

            <!-- 按钮 -->
            <span class="comp-tr-node--btns">
              <!-- 新增 -->
              <el-button
                icon="el-icon-plus"
                size="mini"
                circle
                type="primary"
                @click="handleAdd(node, data)"
                v-if="node.level !== 4"
              ></el-button>

              <!-- 编辑 -->
              <el-button
                icon="el-icon-edit"
                size="mini"
                circle
                type="info"
                @click="handleEdit(node, data)"
              ></el-button>

              <!-- 删除 -->
              <el-button
                icon="el-icon-delete"
                size="mini"
                circle
                type="danger"
                @click="handleDelete(node, data)"
              ></el-button>
            </span>
          </template>
        </div>
      </el-tree>
    </el-card>
  </div>
</template>

<script>
export default {
  name: "ResourceManagement",
  data() {
    return {
      options: [],
      selectValue: "", //下拉选中值
      setTree: [], //tree数据
      NODE_KEY: "id", // id对应字段
      MAX_LEVEL: 4, // 设定最大层级
      NODE_ID_START: 0, // 新增节点id，逐次递减
      expandedList: [], //刷新节点之后展开
      defaultProps: {
        // 默认设置
        children: "children",
        label: "name",
      },
      defaultShowNodes: [],
      id: "",
      initParam: {
        parentId: "",
        name: "",
        title: "",
      },
      loading: false,
      isAdd: false,
    };
  },
  watch: {
    // 监听编辑是否有修改
    setTree: {
      handler(val) {
        this.setTree.forEach((item) => {
          this.defaultShowNodes.push(item.children[0].id);
        });
      },
      deep: true, // 深度监听
    },
    options: {
      handler(val) {},
      deep: true, // 深度监听
    },
  },
  mounted() {
    this.getSelectData();
  },
  methods: {
    selectChange(val) {
      if (val) {
        this.loading = true;
        this.getTreeData(val);
      } else {
        return false;
      }
    },
    handleDelete(_node, _data) {
      // 删除节点
      // 判断是否存在子节点
      if (_data.children && _data.children.length !== 0) {
        this.$notify.error("此目录有子级，不可删除！");
        return false;
      } else {
        this.$confirm("是否删除此目录？", "提示", {
          confirmButtonText: "确认",
          cancelButtonText: "取消",
          type: "warning",
        })
          .then(() => {
            this.delTreeNode(_data.id, _data);
          })
          .catch(() => {});
      }
    },
    handleInput(_node, _data) {
      // 修改节点
      this.editTreeNode(_data);

      // 退出编辑状态
      if (_node.isEdit) {
        this.$set(_node, "isEdit", false);
      }
    },
    handleEdit(_node, _data) {
      // 编辑节点
      // 设置编辑状态
      if (!_node.isEdit) {
        this.$set(_node, "isEdit", true);
      }

      // 输入框聚焦
      this.$nextTick(() => {
        if (this.$refs["slotTreeInput" + _data.id]) {
          this.$refs["slotTreeInput" + _data.id].$refs.input.focus();
        }
      });
    },
    handleAdd(_node, _data) {
      // 判断层级
      if (_node.level >= this.MAX_LEVEL) {
        this.$notify.warning("当前已达到" + this.MAX_LEVEL + "级，无法新增！");
        return false;
      }

      this.$prompt("请输入目录名称", "新增目录", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
      })
        .then(({ value }) => {
          this.initParam.parentId = _data.id;
          this.initParam.name = value;
          this.initParam.title = _data.title;
          this.loading = true;
          this.addTreeNode(this.initParam, _node);
        })
        .catch(() => {
          this.$notify.warning("操作已取消！");
        });

      // 展开节点
      if (!_node.expanded) {
        _node.expanded = true;
      }
    },
    //获取下拉数据
    async getSelectData() {
      let data = await this.$api.selectData();
      this.options = data.data;
    },

    //获取列表数据
    async getTreeData(id) {
      this.id = id;
      this.setTree = [];
      let data = await this.$api.TreeData({ id: id });
      this.setTree.push(data.data);
      if (this.setTree) {
        this.loading = false;
      }
    },

    //异步添加数据
    async addTreeNode(obj) {
      let data = await this.$api.addTreeNode(obj);
      if (data) {
        this.getTreeData(this.id);
        this.loading = false;
      }

      if (data.status == 200 && data.data == "success") {
        this.$notify({
          message: `${data.msg}`,
          type: "success",
        });
      } else if (data.status == 200 && data.data == "failure") {
        this.$notify({
          message: `${data.msg}`,
          type: "error",
        });
      }
    },

    //异步修改数据
    async editTreeNode(val) {
      let data = await this.$api.editTreeNode(val);
      this.getSelectData();
      if (data.status == 200 && data.data == "success") {
        this.$notify({
          message: `${data.msg}`,
          type: "success",
        });
      }
    },

    //异步删除数据
    async delTreeNode(id, _data) {
      let data = await this.$api.delTreeNode(id);
      if (data.status == 200 && data.data == "success") {
        if (this.$refs.SlotTree) {
          this.$refs.SlotTree.remove(_data);
          this.$notify({
            showClose: true,
            message: `${data.msg}`,
            type: "success",
          });
        }
      }
    },
  },
};
</script>

<style lang="scss" scoped>
// 显示按钮
.show-btns {
  opacity: 1;
}
::v-deep .el-input {
  font-size: 0.18rem;
}

::v-deep .el-tree-node__content {
  height: 0.6rem;
}
::v-deep .el-input__inner:focus {
  border: 1px solid #dcdfe6;
}

.box_card {
  width: 50vw;
  height: auto;
  margin: 40px auto;
}
.header_box {
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.comp-tree {
  max-height: 80vh;
  // 顶部按钮
  // 自定义节点
  .comp-tr-node {
    // label
    .comp-tr-node--name {
      display: inline-block;
      line-height: 40px;
      min-height: 40px;
      font-size: 20px;
    }
    // button
    .comp-tr-node--btns {
      margin-left: 20px;
      opacity: 0;
      transition: opacity 0.1s;
      .el-button {
        transform: scale(0.8); // 缩小按钮
        & + .el-button {
          margin-left: 2px;
        }
      }
    }
  }
  // 高亮显示按钮
  .is-current {
    & > .el-tree-node__content {
      .comp-tr-node--btns {
        @extend .show-btns;
      }
    }
  }
  // 悬浮显示按钮
  .el-tree-node__content {
    &:hover {
      .comp-tr-node--btns {
        @extend .show-btns;
      }
    }
  }
}
</style>